﻿ package com.everydayflash.pv3d {
	
	import Bend;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFormat;
	
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.display.StageAlign;

	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cone;
	import org.papervision3d.objects.primitives.Cylinder;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.core.proto.MaterialObject3D;
	import org.papervision3d.materials.WireframeMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.primitives.Cube;
	
	import org.papervision3d.view.Viewport3D;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.render.BasicRenderEngine;

	public class MultibendDemo extends Sprite {
		
		private var viewport:Viewport3D;
		private var scene:Scene3D;
		private var camera:Camera3D;
		private var renderer:BasicRenderEngine;
		
		private var topBar:TopBar;
		
		private var do3d:DisplayObject3D;
		private var do3dBend:Bend;

		private var vw:Number = 800;
		private var vh:Number = 600;

		private var primitives:Array;
		private var pointer:int;
		
		/** Use this as document class */
		public function MultibendDemo() {
			stage.quality = StageQuality.LOW;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			initPapervision3D();
			build3D();
			
			topBar = new TopBar();
			addChild(topBar);
			
			resize();

			addEventListener(Event.ENTER_FRAME, render);
			stage.addEventListener(MouseEvent.CLICK, swapPrimitive);
			stage.addEventListener(Event.RESIZE, resize);
		}
		
		private function swapPrimitive(me:MouseEvent = null):void {
			if (me != null) {
				do3dBend.reset();
				scene.removeChild(do3d);
				do3d = null;
			}
			
			do3d = primitives[pointer];
			do3dBend = new Bend(do3d);
			scene.addChild(do3d);
			
			pointer = (pointer + 1) % primitives.length;
		}

		private function initPapervision3D():void {
			viewport = new Viewport3D(vw, vh);
			addChild(viewport);
			scene = new Scene3D();
			camera = new Camera3D();
			camera.zoom = 10;
			camera.z = 800;
			camera.y = 300;
			
			renderer = new BasicRenderEngine();
		}
		
		private function build3D():void {
			var mat:WireframeMaterial = new WireframeMaterial(0xd4a134);
			mat.doubleSided = true;
			
			var m:MaterialsList = new MaterialsList();
			m.addMaterial(mat, "all");
			
			primitives = new Array();
			primitives.push(new Cube(m, 400, 30, 30, 25, 3, 3));
			primitives.push(new Cylinder(mat, 20, 300, 12, 16));
			primitives.push(new Cone(mat, 50, 400, 16, 12));
			primitives.push(new Sphere(mat, 100, 12, 12));
			primitives.push(new Plane(mat, 300, 300, 5, 5));
			
			pointer = 0;
			swapPrimitive();
			camera.lookAt(do3d);
		}
		
		private function resize(e:Event=null):void {
			viewport.x = stage.stageWidth / 2  - vw / 2;
			viewport.y = stage.stageHeight / 2  - vh / 2;
			
			graphics.clear();
			graphics.lineStyle(1, 0x000000, .2);
			var o:int = 50;
			graphics.drawRect(o, 30+o, stage.stageWidth-o*2, stage.stageHeight-30-o*2);
			
			topBar.resize();
		}
		
		private function render(e:Event):void {
			var offset:Number = stage.mouseY / stage.stageHeight;
			var force:Number = stage.mouseX / stage.stageWidth * 4 - 2;
			
			do3dBend.quickBend(force, offset);
			
			do3d.rotationY += 1;
			renderer.renderScene(scene, camera, viewport);
		}
	}
}





